//一个任务管理器系统可以让用户管理他们的任务，每个任务有一个优先级。这个系统需要高效地处理添加、修改、执行和删除任务的操作。 
//
// 请你设计一个 TaskManager 类： 
//
// 
// TaskManager(vector<vector<int>>& tasks) 初始化任务管理器，初始化的数组格式为 [userId, taskId, 
//priority] ，表示给 userId 添加一个优先级为 priority 的任务 taskId 。 
// void add(int userId, int taskId, int priority) 表示给用户 userId 添加一个优先级为 
//priority 的任务 taskId ，输入 保证 taskId 不在系统中。 
// void edit(int taskId, int newPriority) 更新已经存在的任务 taskId 的优先级为 newPriority 。输入
// 保证 taskId 存在于系统中。 
// void rmv(int taskId) 从系统中删除任务 taskId 。输入 保证 taskId 存在于系统中。 
// int execTop() 执行所有用户的任务中优先级 最高 的任务，如果有多个任务优先级相同且都为 最高 ，执行 taskId 最大的一个任务。执行完任
//务后，taskId 从系统中 删除 。同时请你返回这个任务所属的用户 userId 。如果不存在任何任务，返回 -1 。 
// 
//
// 注意 ，一个用户可能被安排多个任务。 
//
// 
//
// 示例 1： 
//
// 
// 输入： ["TaskManager", "add", "edit", "execTop", "rmv", "add", "execTop"] [[[[1,
// 101, 10], [2, 102, 20], [3, 103, 15]]], [4, 104, 5], [102, 8], [], [101], [5, 1
//05, 15], []] 
// 
//
// 输出： [null, null, null, 3, null, null, 5] 
//
// 解释： TaskManager taskManager = new TaskManager([[1, 101, 10], [2, 102, 20], [3
//, 103, 15]]); // 分别给用户 1 ，2 和 3 初始化一个任务。
// taskManager.add(4, 104, 5); // 给用户 4 添加优先级为 5 的任务 104 。
// taskManager.edit(102, 8); // 更新任务 102 的优先级为 8 。
// taskManager.execTop(); // 返回 3 。执行用户 3 的任务 103 。
// taskManager.rmv(101); // 将系统中的任务 101 删除。
// taskManager.add(5, 105, 15); // 给用户 5 添加优先级为 15 的任务 105 。
// taskManager.execTop(); // 返回 5 。执行用户 5 的任务 105 。
//
// 
//
// 提示： 
//
// 
// 1 <= tasks.length <= 10⁵ 
// 0 <= userId <= 10⁵ 
// 0 <= taskId <= 10⁵ 
// 0 <= priority <= 10⁹ 
// 0 <= newPriority <= 10⁹ 
// add ，edit ，rmv 和 execTop 的总操作次数 加起来 不超过 2 * 10⁵ 次。 
// 输入保证 taskId 是合法的。 
// 
//
// Related Topics 设计 哈希表 有序集合 堆（优先队列） 👍 24 👎 0


package LeetCode.editor.cn;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;

/**
 * @author ldltd
 * @date 2025-09-18 23:51:46
 * @description 3408.设计任务管理器
 */
public class DesignTaskManager{
	 public static void main(String[] args) {
	 	 //测试代码
	 	 DesignTaskManager fun=new DesignTaskManager();


	 }

//力扣代码
//leetcode submit region begin(Prohibit modification and deletion)
class TaskManager1 {
         //用户队列
    private Map<Integer, PriorityQueue<int[]>> userTasks;
    // 任务队列
    private Map<Integer, int[]> taskInfo;
    //全局堆
    private PriorityQueue<int[]> globalHeap;

    public TaskManager1(List<List<Integer>> tasks) {
        userTasks = new HashMap<>();
        taskInfo = new HashMap<>();
        globalHeap = new PriorityQueue<>((a, b) -> {
            if (a[0] != b[0]) return Integer.compare(b[0], a[0]);
            else return Integer.compare(b[1], a[1]);
        });
        for (List<Integer> task : tasks) {
            add(task.get(0), task.get(1), task.get(2));
        }
    }

    public void add(int userId, int taskId, int priority) {
        // 如果taskId已存在（由于惰性删除未清理），先移除
        if (taskInfo.containsKey(taskId)) {
            rmv(taskId);
        }
        int[] task = new int[]{priority, taskId, userId};
        taskInfo.put(taskId, task);
        userTasks.computeIfAbsent(userId, k -> new PriorityQueue<>((a, b) -> {
            if (a[0] != b[0]) return Integer.compare(b[0], a[0]);
            else return Integer.compare(b[1], a[1]);
        })).add(new int[]{priority, taskId});
        globalHeap.add(new int[]{priority, taskId, userId});
    }

    public void edit(int taskId, int newPriority) {
        int[] oldTask = taskInfo.get(taskId);
        if (oldTask == null) return;
        int userId = oldTask[2];
        int oldPriority = oldTask[0];
        if (oldPriority == newPriority) return;

        // 从用户堆中移除旧任务
        PriorityQueue<int[]> userHeap = userTasks.get(userId);
        if (userHeap != null) {
            userHeap.removeIf(e -> e[1] == taskId);
        }

        int[] newTask = new int[]{newPriority, taskId, userId};
        taskInfo.put(taskId, newTask);
        userHeap.add(new int[]{newPriority, taskId});
        globalHeap.add(new int[]{newPriority, taskId, userId});
    }

    public void rmv(int taskId) {
        int[] task = taskInfo.remove(taskId);
        if (task != null) {
            int userId = task[2];
            PriorityQueue<int[]> userHeap = userTasks.get(userId);
            if (userHeap != null) {
                userHeap.removeIf(e -> e[1] == taskId);
            }
        }
    }

    public int execTop() {
        while (!globalHeap.isEmpty()) {
            int[] top = globalHeap.peek();
            int priority = top[0];
            int taskId = top[1];
            int userId = top[2];
            int[] currentTaskInfo = taskInfo.get(taskId);
            if (currentTaskInfo == null) {
                globalHeap.poll();
                continue;
            }
            if (currentTaskInfo[0] != priority || currentTaskInfo[2] != userId) {
                globalHeap.poll();
                continue;
            }
            globalHeap.poll();
            taskInfo.remove(taskId);
            PriorityQueue<int[]> userHeap = userTasks.get(userId);
            if (userHeap != null) {
                userHeap.removeIf(e -> e[1] == taskId);
            }
            return userId;
        }
        return -1;
    }
}
    // 其实userID没特别的用处
    class TaskManager2 {
        private Map<Integer, int[]> taskInfo;
        // 用来取最大优先级的任务
        private PriorityQueue<int[]> heap;

        public TaskManager2(List<List<Integer>> tasks) {
            taskInfo = new HashMap<>();
            heap = new PriorityQueue<>((a, b) -> {
                if (a[0] != b[0]) {
                    return b[0] - a[0];
                }
                return b[1] - a[1];
            });

            for (List<Integer> task : tasks) {
                int userId = task.get(0), taskId = task.get(1), priority = task.get(2);
                taskInfo.put(taskId, new int[]{priority, userId});
                heap.offer(new int[]{priority, taskId});
            }
        }

        public void add(int userId, int taskId, int priority) {
            taskInfo.put(taskId, new int[]{priority, userId});
            heap.offer(new int[]{priority, taskId});
        }

        public void edit(int taskId, int newPriority) {
            if (taskInfo.containsKey(taskId)) {
                taskInfo.get(taskId)[0] = newPriority;
                heap.offer(new int[]{newPriority, taskId});
            }
        }

        public void rmv(int taskId) {
            taskInfo.remove(taskId);
        }

        public int execTop() {
            while (!heap.isEmpty()) {
                int[] task = heap.poll();
                int priority = task[0], taskId = task[1];

                if (taskInfo.containsKey(taskId) && taskInfo.get(taskId)[0] == priority) {
                    int userId = taskInfo.get(taskId)[1];
                    taskInfo.remove(taskId);
                    return userId;
                }
            }
            return -1;
        }
    }
    class TaskManager {
        // taskId -> (priority, userId)
        private final Map<Integer, int[]> mp = new HashMap<>();

        // (priority, taskId, userId)
        private final PriorityQueue<int[]> pq =
                new PriorityQueue<>((a, b) -> a[0] != b[0] ? b[0] - a[0] : b[1] - a[1]);

        public TaskManager(List<List<Integer>> tasks) {
            for (List<Integer> task : tasks) {
                add(task.get(0), task.get(1), task.get(2));
            }
        }

        public void add(int userId, int taskId, int priority) {
            mp.put(taskId, new int[]{priority, userId});
            pq.offer(new int[]{priority, taskId, userId});
        }

        public void edit(int taskId, int newPriority) {
            // 懒修改
            int userId = mp.get(taskId)[1];
            add(userId, taskId, newPriority);
        }

        public void rmv(int taskId) {
            // 懒删除
            mp.get(taskId)[0] = -1;
        }

        public int execTop() {
            while (!pq.isEmpty()) {
                int[] top = pq.poll();
                int priority = top[0], taskId = top[1], userId = top[2];
                int[] p = mp.get(taskId);
                if (p[0] == priority && p[1] == userId) {
                    rmv(taskId);
                    return userId;
                }
                // else 货不对板，堆顶和 mp 中记录的不一样，说明堆顶数据已被修改或删除，不做处理
            }
            return -1;
        }
    }


/**
 * Your TaskManager object will be instantiated and called as such:
 * TaskManager obj = new TaskManager(tasks);
 * obj.add(userId,taskId,priority);
 * obj.edit(taskId,newPriority);
 * obj.rmv(taskId);
 * int param_4 = obj.execTop();
 */
//leetcode submit region end(Prohibit modification and deletion)

}
